<!DOCTYPE html>
<html lang="zh-CN">

<head>
  <meta charset="UTF-8">
  <meta name="author" content="wangbo">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>

<body>

  <!-- vue2 响应式的原理 用的是Object.defineProperty -->
  <script>




    // 依赖类
    function Dep () {
      this.subs = [];
    }

    Dep.prototype.addSub = function (sub) {
      this.subs.push(sub);
    };

    Dep.prototype.notify = function () {
      this.subs.forEach(sub => {
        sub.update(); // 执行Watcher的更新函数
      });
    };

    // 创建Watcher
    Dep.target = {
      update: function () {
        console.log('更新虚拟DOM...');
      }
    };


    // 定义响应式对象
    function defineReactive (obj, key, val) {
      var dep = new Dep();
      Object.defineProperty(obj, key, {
        enumerable: true,
        configurable: true,
        get: function reactiveGetter () {
          dep.addSub(Dep.target); // 添加订阅者到依赖集合
          return val;
        },
        set: function reactiveSetter (newVal) {
          if (newVal === val) return;
          val = newVal;
          dep.notify(); // 通知所有订阅者
        }
      });
    }

    // 定义观察者
    function observe (data) {
      if (typeof data !== 'object' || data === null) {
        return;
      }

      Object.keys(data).forEach(key => {
        defineReactive(data, key, data[key]);
      });
    }

    // 响应式数据对象
    var data = { name: 'Vue' };

    // 应用响应式
    observe(data);

    // 设置属性，触发依赖收集和响应性更新
    data.name = 'Vue 2';
  </script>
</body>

</html>